﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Configuration;
using Oracle.DataAccess;
using Oracle.DataAccess.Client;
using Oracle.DataAccess.Types;
using System.Diagnostics;

namespace Flighttracker
{
    public class Flighttracker
    {
        public List<Luchtvaartmaatschappij> Luchtvaartmaatschappijen { get; private set; }
        public List<Vliegtuigtype> Vliegtuigtypen { get; private set; }
        public List<Luchthaven> Luchthavens { get; private set; }
        public List<Radar> Radars { get; private set; }
        public List<Vliegtuig> Vliegtuigen { get; private set; }
        public List<Piloot> Piloten { get; private set; }
        public List<Vlucht> Vluchten { get; private set; }
        public List<PilootInzet> PilootInzetten { get; private set; }
        public List<Baangebruik> Baangebruik { get; private set; }
        public List<Vluchtstatus> Vluchtstatussen { get; private set; }

        private OracleConnection conn;

        private static Flighttracker instance;

        /// <summary>
        /// Constructor
        /// De verkrijgallegegevens methode wordt aangeroepen zodra de constructor is aangeroepen.
        /// </summary>
        private Flighttracker()
        {
            Luchtvaartmaatschappijen = new List<Luchtvaartmaatschappij>();
            Vliegtuigtypen = new List<Vliegtuigtype>();
            Luchthavens = new List<Luchthaven>();
            Radars = new List<Radar>();
            Vliegtuigen = new List<Vliegtuig>();
            Piloten = new List<Piloot>();
            Vluchten = new List<Vlucht>();
            PilootInzetten = new List<PilootInzet>();
            Baangebruik = new List<Baangebruik>();
            Vluchtstatussen = new List<Vluchtstatus>();

            conn = new OracleConnection(ConfigurationManager.ConnectionStrings["oracle"].ConnectionString);
        }

        public static Flighttracker Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new Flighttracker();
                }
                return instance;
            }
        }

        /// <summary>
        /// Alle gegevens worden uit te database gehaald en op basis van daarvan objecten aangemaakt.
        /// </summary>
        public void VerkrijgAlleGegevens()
        {
            DataTable lvm = queryCommand("select * from luchtvaartmaatschappij");
            DataTable vliegtuigtype = queryCommand("select * from vliegtuigtype");
            DataTable luchthaven = queryCommand("select * from luchthaven");
            DataTable radar = queryCommand("select * from radar");
            DataTable vliegtuig = queryCommand("select * from vliegtuig");
            DataTable piloot = queryCommand("select * from piloot");
            DataTable vlucht = queryCommand("select * from vlucht");
            DataTable pilootinzet = queryCommand("select * from pilootinzet");
            DataTable baangebruik = queryCommand("select * from baangebruik");
            DataTable vluchtstatus = queryCommand("select * from vluchtstatus");
            VerwerkGegevens(typeof(Luchtvaartmaatschappij), lvm);
            VerwerkGegevens(typeof(Vliegtuigtype), vliegtuigtype);
            VerwerkGegevens(typeof(Luchthaven), luchthaven);
            VerwerkGegevens(typeof(Radar), radar);
            VerwerkGegevens(typeof(Vliegtuig), vliegtuig);
            VerwerkGegevens(typeof(Piloot), piloot);
            VerwerkGegevens(typeof(Vlucht), vlucht);
            VerwerkGegevens(typeof(PilootInzet), pilootinzet);
            VerwerkGegevens(typeof(Baangebruik), baangebruik);
            VerwerkGegevens(typeof(Vluchtstatus), vluchtstatus);
        }

        /// <summary>
        /// Verstuurt een query naar de database om gegevens op te halen.
        /// </summary>
        /// <param name="query"></param>
        private DataTable queryCommand(string query)
        {
            // Connects to database
            conn.Open();

            // Instantiates an OracleCommand with the conn and query arguments 
            OracleCommand cmd = new OracleCommand(query, conn);

            // Sets CommandType enum to Text so it can handle strings
            cmd.CommandType = CommandType.Text;

            // Creates OracleDataReader object
            OracleDataReader reader = cmd.ExecuteReader();

            DataTable datatable = new DataTable();
            datatable.Load(reader);

            conn.Close();
            return datatable;
        }

        private void VerwerkGegevens(Type t, DataTable dataTable)
        {


            for (int i = 0; i < dataTable.Rows.Count; i++)
            {
                var parameters = new List<string>();

                for (int j = 0; j < dataTable.Columns.Count; j++)
                {
                    parameters.Add(dataTable.Rows[i][j].ToString());
                }

                var instance = Activator.CreateInstance(t, parameters);

                CheckTypeEnVoegAanLijstToe(t, instance);
            }
        }

        private void CheckTypeEnVoegAanLijstToe(Type t, Object instance)
        {
            if (t == typeof(Luchtvaartmaatschappij))
                Luchtvaartmaatschappijen.Add((Luchtvaartmaatschappij)instance);

            if (t == typeof(Vliegtuigtype))
                Vliegtuigtypen.Add((Vliegtuigtype)instance);

            if (t == typeof(Luchthaven))
                Luchthavens.Add((Luchthaven)instance);

            if (t == typeof(Vliegtuig))
                Vliegtuigen.Add((Vliegtuig)instance);

            if (t == typeof(Piloot))
                Piloten.Add((Piloot)instance);

            if (t == typeof(Radar))
                Radars.Add((Radar)instance);

            if (t == typeof(Vlucht))
                Vluchten.Add((Vlucht)instance);

            if (t == typeof(PilootInzet))
                PilootInzetten.Add((PilootInzet)instance);

            if (t == typeof(Baangebruik))
                Baangebruik.Add((Baangebruik)instance);

            if (t == typeof(Vluchtstatus))
                Vluchtstatussen.Add((Vluchtstatus)instance);
        }

        public Object ZoekObject(string id)
        {
            var objectList = new List<ISearchable>();

            objectList.AddRange(Luchtvaartmaatschappijen);
            objectList.AddRange(Vliegtuigtypen);
            objectList.AddRange(Luchthavens);
            objectList.AddRange(Vliegtuigen);
            objectList.AddRange(Piloten);
            objectList.AddRange(Vluchten);
            objectList.AddRange(PilootInzetten);
            objectList.AddRange(Baangebruik);
            objectList.AddRange(Vluchtstatussen);

            foreach (ISearchable obj in objectList)
            {
                if (obj.ZoekUniekID(id))
                {
                    return obj;
                }
            }

            return null;
        }
    }
}